#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QTime>
#include <QCloseEvent>
#include <QIntValidator>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 设置对话框样式
    resize(600, 400);
    setWindowFlags(windowFlags()& ~Qt::WindowMaximizeButtonHint);
    setFixedSize(this->width(), this->height());
    setWindowIcon(QIcon(":/res/icon.ico"));

    // 设置lineedit格式
    QValidator *validator=new QIntValidator(0,65535);
    ui->lineEditServerPort->setValidator(validator);

    // 设置按钮样式
    ui->pushButton->setFixedWidth(100);
    ui->pushButton->setFixedHeight(120);
    isConnected = false;

    // 默认数据
    ui->lineEditIPAddress->setText("127.0.0.1");
    ui->lineEditServerPort->setText("2001");

    // 初始化网络
    netCore = new NetCore();
    connect(netCore, &NetCore::sigError, this, &MainWindow::on_error);
    connect(netCore, &NetCore::sigServer, this, &MainWindow::on_server);
    connect(netCore, &NetCore::sigScConfig, this, &MainWindow::on_sc_config);
    connect(netCore, &NetCore::sigScSig, this, &MainWindow::on_sc_sig);

    // 打开调试模式
    //rdp.isDebug = true;
}

MainWindow::~MainWindow()
{
    netCore->stop();
    delete netCore;
    delete ui;
}

// ***********************  以下是私有成员函数 **************************

// 在textBrowser的末尾添加一行带有固定格式的数据
void MainWindow::insertLineText(QString text)
{
    ui->textBrowser->append(QString("%1 %2").arg(QTime::currentTime().toString("hh:mm:ss")).arg(text));
}

// ***********************  以下是UI槽函数 *****************************

// 连接/断开按钮槽函数
void MainWindow::on_pushButton_clicked()
{
    if(!isConnected)
    {
        qDebug() << "连接服务器";
        int serverPort = ui->lineEditServerPort->text().toInt();
        QString ipAddress = ui->lineEditIPAddress->text();

        netCore->config(ipAddress, serverPort);
        netCore->start();
    }
    else
    {
        qDebug() << "断开服务器";
        netCore->stop();
    }
}

//// ***********************  以下是网络通讯槽函数 *****************************

// 槽函数 - 服务器信息（连接、断开）
void MainWindow::on_server(int code, QString msg)
{
    insertLineText(msg);
    if(code == NET_CONNECTED)
    {
        isConnected = true;
        ui->pushButton->setText("断开");
    }else
    {
        isConnected = false;
        ui->pushButton->setText("连接");
    }

}

// 槽函数 - 错误信息
void MainWindow::on_error(int code, QString msg)
{
    insertLineText(msg);
}

// 槽函数 - 配置信息
void MainWindow::on_sc_config(int scWidth, int scHeight, int indexX, int indexY, int bit, int fps)
{
    insertLineText(QString("接收配置信息：[宽度:%1,高度:%2,X轴分块:%3,Y轴分块:%4,灰度:%5,刷新率:%6]")
                               .arg(scWidth).arg(scHeight).arg(indexX).arg(indexY).arg(bit).arg(fps));

    this->scWidth = scWidth;
    this->scHeight = scHeight;
    this->indexX = indexX;
    this->indexY = indexY;
    this->bit = bit;
    this->fps = fps;

    // 开启位图流传输
    insertLineText(QString("开始传送屏幕数据 | 间隔：%1ms").arg(fps));
    scDataThread = new ScDataThread();
    connect(scDataThread, &ScDataThread::sigUImsg, this, &MainWindow::on_thread_interface);
    scDataThread->setConfig(this->indexX, this->indexY, this->scWidth, this->scHeight, this->fps, this->bit, netCore);
    scDataThread->start();
}


void MainWindow::on_sc_sig(int code)
{
    qDebug() << "收到结束传输信号：" << code;
    if(scDataThread)
    {
        if(code == 1)
        {
            disconnect(scDataThread, &ScDataThread::sigUImsg, this, &MainWindow::on_thread_interface);
            scDataThread->stop();
            scDataThread->wait();
            delete scDataThread;
            scDataThread = nullptr;
            insertLineText("抓屏线程已成功停止");
        }
    }
}

void MainWindow::on_thread_interface(QString msg)
{
    insertLineText(msg);
}

// ***********************  以下窗口消息重载函数 ***************************
// 关闭窗口消息重载
void MainWindow::closeEvent(QCloseEvent *e)
{
    if(scDataThread)
    {
        scDataThread->stop();
        scDataThread->wait();
        delete scDataThread;
        scDataThread = nullptr;
        insertLineText("抓屏线程已成功停止");
    }

    e->accept();
}
